home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / badlands.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  9KB  |  327 lines

  1. /***************************************************************************
  2.  
  3.     Atari Bad Lands hardware
  4.  
  5. ***************************************************************************/
  6.  
  7.  
  8. #include "driver.h"
  9. #include "machine/atarigen.h"
  10. #include "vidhrdw/generic.h"
  11.  
  12. #define XCHARS 42
  13. #define YCHARS 30
  14.  
  15. #define XDIM (XCHARS*8)
  16. #define YDIM (YCHARS*8)
  17.  
  18.  
  19.  
  20. /*************************************
  21.  *
  22.  *    Statics
  23.  *
  24.  *************************************/
  25.  
  26. static struct atarigen_pf_state pf_state;
  27.  
  28.  
  29.  
  30. /*************************************
  31.  *
  32.  *    Prototypes
  33.  *
  34.  *************************************/
  35.  
  36. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  37. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *data);
  38.  
  39. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param);
  40.  
  41.  
  42.  
  43. /*************************************
  44.  *
  45.  *    Generic video system start
  46.  *
  47.  *************************************/
  48.  
  49. int badlands_vh_start(void)
  50. {
  51.     static struct atarigen_mo_desc mo_desc =
  52.     {
  53.         32,                  /* maximum number of MO's */
  54.         4,                   /* number of bytes per MO entry */
  55.         0x80,                /* number of bytes between MO words */
  56.         0,                   /* ignore an entry if this word == 0xffff */
  57.         -1, 0, 0x3f,         /* link = (data[linkword] >> linkshift) & linkmask */
  58.         0                    /* render in reverse link order */
  59.     };
  60.  
  61.     static struct atarigen_pf_desc pf_desc =
  62.     {
  63.         8, 8,                /* width/height of each tile */
  64.         64, 64,                /* number of tiles in each direction */
  65.         1                    /* non-scrolling */
  66.     };
  67.  
  68.     /* initialize statics */
  69.     memset(&pf_state, 0, sizeof(pf_state));
  70.  
  71.     /* initialize the playfield */
  72.     if (atarigen_pf_init(&pf_desc))
  73.         return 1;
  74.  
  75.     /* initialize the motion objects */
  76.     if (atarigen_mo_init(&mo_desc))
  77.     {
  78.         atarigen_pf_free();
  79.         return 1;
  80.     }
  81.  
  82.     /*
  83.      * if we are palette reducing, do the simple thing by marking everything used except for
  84.      * the transparent sprite and alpha colors; this should give some leeway for machines
  85.      * that can't give up all 256 colors
  86.      */
  87.     if (palette_used_colors)
  88.     {
  89.         int i;
  90.  
  91.         memset(palette_used_colors, PALETTE_COLOR_USED, Machine->drv->total_colors * sizeof(UINT8));
  92.         for (i = 0; i < 8; i++)
  93.             palette_used_colors[0x80 + i * 16] = PALETTE_COLOR_TRANSPARENT;
  94.     }
  95.  
  96.     return 0;
  97. }
  98.  
  99.  
  100.  
  101. /*************************************
  102.  *
  103.  *    Video system shutdown
  104.  *
  105.  *************************************/
  106.  
  107. void badlands_vh_stop(void)
  108. {
  109.     atarigen_pf_free();
  110.     atarigen_mo_free();
  111. }
  112.  
  113.  
  114.  
  115. /*************************************
  116.  *
  117.  *    Periodic scanline updater
  118.  *
  119.  *************************************/
  120.  
  121. void badlands_scanline_update(int scanline)
  122. {
  123.     /* update motion objects */
  124.     if (scanline == 0)
  125.         atarigen_mo_update(atarigen_spriteram, 0, scanline);
  126. }
  127.  
  128.  
  129.  
  130. /*************************************
  131.  *
  132.  *    Playfield bank write handler
  133.  *
  134.  *************************************/
  135.  
  136. WRITE_HANDLER( badlands_pf_bank_w )
  137. {
  138.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  139.     int newword = COMBINE_WORD(oldword, data);
  140.  
  141.     if (oldword != newword)
  142.     {
  143.         pf_state.param[0] = data & 1;
  144.         atarigen_pf_update(&pf_state, cpu_getscanline());
  145.     }
  146. }
  147.  
  148.  
  149.  
  150. /*************************************
  151.  *
  152.  *    Playfield RAM write handler
  153.  *
  154.  *************************************/
  155.  
  156. WRITE_HANDLER( badlands_playfieldram_w )
  157. {
  158.     int oldword = READ_WORD(&atarigen_playfieldram[offset]);
  159.     int newword = COMBINE_WORD(oldword, data);
  160.  
  161.     if (oldword != newword)
  162.     {
  163.         WRITE_WORD(&atarigen_playfieldram[offset], newword);
  164.         atarigen_pf_dirty[offset / 2] = 0xff;
  165.     }
  166. }
  167.  
  168.  
  169.  
  170. /*************************************
  171.  *
  172.  *    Main refresh
  173.  *
  174.  *************************************/
  175.  
  176. void badlands_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  177. {
  178.     int i;
  179.  
  180.     /* remap if necessary */
  181.     if (palette_recalc())
  182.         memset(atarigen_pf_dirty, 0xff, atarigen_playfieldram_size / 2);
  183.  
  184.     /* set up the all-transparent overrender palette */
  185.     for (i = 0; i < 16; i++)
  186.         atarigen_overrender_colortable[i] = palette_transparent_pen;
  187.  
  188.     /* draw the playfield */
  189.     atarigen_pf_process(pf_render_callback, bitmap, &Machine->drv->visible_area);
  190.  
  191.     /* render the motion objects */
  192.     atarigen_mo_process(mo_render_callback, bitmap);
  193.  
  194.     /* update onscreen messages */
  195.     atarigen_update_messages();
  196. }
  197.  
  198.  
  199.  
  200. /*************************************
  201.  *
  202.  *    Playfield rendering
  203.  *
  204.  *************************************/
  205.  
  206. static void pf_render_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  207. {
  208.     const struct GfxElement *gfx = Machine->gfx[0];
  209.     int bank = state->param[0] * 0x1000;
  210.     struct osd_bitmap *bitmap = param;
  211.     int x, y;
  212.  
  213.     /* standard loop over tiles */
  214.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  215.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  216.         {
  217.             int offs = y * 64 + x;
  218.  
  219.             /* update only if dirty */
  220.             if (atarigen_pf_dirty[offs] != state->param[0])
  221.             {
  222.                 int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  223.                 int code = data & 0x1fff;
  224.                 int color = data >> 13;
  225.                 if (code & 0x1000) code += bank;
  226.  
  227.                 drawgfx(atarigen_pf_bitmap, gfx, code, color, 0, 0, 8 * x, 8 * y, 0, TRANSPARENCY_NONE, 0);
  228.                 atarigen_pf_dirty[offs] = state->param[0];
  229.             }
  230.         }
  231.  
  232.     /* then blast the result */
  233.     copybitmap(bitmap, atarigen_pf_bitmap, 0, 0, 0, 0, clip, TRANSPARENCY_NONE, 0);
  234. }
  235.  
  236.  
  237.  
  238. /*************************************
  239.  *
  240.  *    Playfield overrendering
  241.  *
  242.  *************************************/
  243.  
  244. static void pf_overrender_callback(const struct rectangle *clip, const struct rectangle *tiles, const struct atarigen_pf_state *state, void *param)
  245. {
  246.     const struct GfxElement *gfx = Machine->gfx[0];
  247.     int bank = state->param[0] * 0x1000;
  248.     struct osd_bitmap *bitmap = param;
  249.     int x, y;
  250.  
  251.     /* standard loop over tiles */
  252.     for (y = tiles->min_y; y != tiles->max_y; y = (y + 1) & 63)
  253.         for (x = tiles->min_x; x != tiles->max_x; x = (x + 1) & 63)
  254.         {
  255.             int offs = y * 64 + x;
  256. /*            int priority_offs = y * 64 + XCHARS + x / 2;*/
  257.             int data = READ_WORD(&atarigen_playfieldram[offs * 2]);
  258.             int color = data >> 13;
  259.             int code = data & 0x1fff;
  260.             if (code & 0x1000) code += bank;
  261.  
  262.             drawgfx(bitmap, gfx, code, color, 0, 0, 8 * x, 8 * y, clip, TRANSPARENCY_PENS, 0x00ff);
  263.         }
  264. }
  265.  
  266.  
  267.  
  268. /*************************************
  269.  *
  270.  *    Motion object rendering
  271.  *
  272.  *************************************/
  273.  
  274. static void mo_render_callback(const UINT16 *data, const struct rectangle *clip, void *param)
  275. {
  276.     struct GfxElement *gfx = Machine->gfx[1];
  277.     struct osd_bitmap *bitmap = param;
  278.     struct rectangle pf_clip;
  279.  
  280.     /* extract data from the various words */
  281.     int ypos = -(data[1] >> 7);
  282.     int vsize = (data[1] & 0x000f) + 1;
  283.     int code = data[0] & 0x0fff;
  284.     int xpos = data[3] >> 7;
  285.     int color = data[3] & 0x0007;
  286.     int priority = (data[3] >> 3) & 1;
  287.  
  288.     /* adjust for height */
  289.     ypos -= vsize * 8;
  290.  
  291.     /* adjust the final coordinates */
  292.     xpos &= 0x1ff;
  293.     ypos &= 0x1ff;
  294.     if (xpos >= XDIM) xpos -= 0x200;
  295.     if (ypos >= YDIM) ypos -= 0x200;
  296.  
  297.     /* clip the X coordinate */
  298.     if (xpos <= -16 || xpos >= XDIM)
  299.         return;
  300.  
  301.     /* determine the bounding box */
  302.     atarigen_mo_compute_clip_16x16(pf_clip, xpos, ypos, 1, vsize, clip);
  303.  
  304.     /* simple case? */
  305.     if (priority == 1)
  306.     {
  307.         /* draw the motion object */
  308.         atarigen_mo_draw_16x8_strip(bitmap, gfx, code, color, 0, 0, xpos, ypos, vsize, clip, TRANSPARENCY_PEN, 0);
  309.     }
  310.  
  311.     /* otherwise, make it tricky */
  312.     else
  313.     {
  314.         /* draw an instance of the object in all transparent pens */
  315.         atarigen_mo_draw_transparent_16x8_strip(bitmap, gfx, code, 0, 0, xpos, ypos, vsize, clip, TRANSPARENCY_PEN, 0);
  316.  
  317.         /* and then draw it normally on the temp bitmap */
  318.         atarigen_mo_draw_16x8_strip(atarigen_pf_overrender_bitmap, gfx, code, color, 0, 0, xpos, ypos, vsize, clip, TRANSPARENCY_NONE, 0);
  319.  
  320.         /* overrender the playfield on top of that that */
  321.         atarigen_pf_process(pf_overrender_callback, atarigen_pf_overrender_bitmap, &pf_clip);
  322.  
  323.         /* finally, copy this chunk to the real bitmap */
  324.         copybitmap(bitmap, atarigen_pf_overrender_bitmap, 0, 0, 0, 0, &pf_clip, TRANSPARENCY_THROUGH, palette_transparent_pen);
  325.     }
  326. }
  327.